//
//  FileImagePickerPlugin.m
//  file_picker_copy
//
//  Created by FXY on 2022/2/25.
//

#import "FileImagePickerPlugin.h"

#import <MobileCoreServices/MobileCoreServices.h>

#import <MediaPlayer/MediaPlayer.h>

#import "FileUtils.h"
#import "ImageUtils.h"

#import "FLTImagePickerImageUtil.h"
#import "FLTImagePickerPhotoAssetUtil.h"

#import "FLTPHPickerSaveImageToPathOperation.h"

@import DKImagePickerController;

#if __has_include(<PhotosUI/PHPicker.h>) || __has_include("PHPicker.h")
#define FIPP_PHPicker
#import <PhotosUI/PHPicker.h>
#endif

/// 选择类型
typedef NS_ENUM(NSUInteger, FileImagePickType)
{
    FileImagePickTypeCamera = 0,  // 相机
    FileImagePickTypePhotoLibrary,    // 相册
    FileImagePickTypeFile,  // 文件
};

/// 资源类型
typedef NS_ENUM(NSUInteger, FileImagePickSource)
{
    FileImagePickSourceImage = 0,  // 图片
    FileImagePickSourceVideo,    // 视频
    FileImagePickSourceAll,  // 所有
};

@interface FileImagePickerPlugin ()<UINavigationControllerDelegate, UIDocumentPickerDelegate, UIDocumentInteractionControllerDelegate,UIImagePickerControllerDelegate,MPMediaPickerControllerDelegate
#ifdef FIPP_PHPicker
, PHPickerViewControllerDelegate
#endif
>

@property (nonatomic) FlutterResult result;
@property (nonatomic) FlutterEventSink eventSink;
///file_piker 8.0.6 start
@property (nonatomic) UIImagePickerController *galleryPickerController;
@property (nonatomic) UIDocumentPickerViewController *documentPickerController;
@property (nonatomic) UIDocumentInteractionController *interactionController;
@property (nonatomic) MPMediaPickerController *audioPickerController;
//@property (nonatomic) NSArray<NSString *> * allowedExtensions;//对应fileAllowedExtensions
//@property (nonatomic) BOOL loadDataToMemory;//对应字段 fileWithData
@property (nonatomic) BOOL fileAllowCompression;
@property (nonatomic) dispatch_group_t group;
@property (nonatomic) BOOL isSaveFile;
///file_piker 8.0.6  end
@property(strong, nonatomic) NSDictionary *arguments;

/// 来源File
@property (nonatomic, assign) BOOL fromFile;


/// 选择类型
@property (nonatomic, assign) FileImagePickType pickType;
/// 资源类型
@property (nonatomic, assign) FileImagePickSource sourceType;

/// 单选是否可以裁剪
@property (nonatomic, assign) BOOL imageAllowsEditing;

@property (nonatomic, assign) BOOL imageAllowsCompression;

/// 图片HEIC格式转换jpg
@property (nonatomic, assign) BOOL imageHEICtoJPG;
/// 图片是否旋转
@property (nonatomic, assign) BOOL isRotation;

/// 相册多选数量限制，0-无上限
@property (nonatomic, assign) NSInteger selectionLimit;


/// 文件
@property (nonatomic, assign) BOOL fileIsDirectory;

/// 文件扩展名，文件支持类型
@property (nonatomic, strong) NSArray<NSString *> * fileAllowedExtensions;


@property (nonatomic, assign) BOOL fileWithData;

@property (nonatomic, assign) NSTimeInterval videoMaximumDuration;

@property(strong, nonatomic) NSNumber *imageMaxWidth;

@property(strong, nonatomic) NSNumber *imageMaxHeight;
@property(strong, nonatomic) NSNumber *imageQuality;

@property(strong, nonatomic) NSString *customSavePath;

@end

@implementation FileImagePickerPlugin


#pragma mark - 桥接
+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar> *)registrar {
    ///注册多通道
    FlutterMethodChannel* channel = [FlutterMethodChannel
                                     methodChannelWithName:@"miguelruivo.flutter.plugins.filepicker"
                                     binaryMessenger:[registrar messenger]];

    FlutterEventChannel* eventChannel = [FlutterEventChannel
                                         eventChannelWithName:@"miguelruivo.flutter.plugins.filepickerevent"
                                         binaryMessenger:[registrar messenger]];

    FileImagePickerPlugin* instance = FileImagePickerPlugin.new;

    [registrar addMethodCallDelegate:instance channel:channel];
    [eventChannel setStreamHandler:instance];

    FlutterMethodChannel *imageChannel =
          [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/image_picker"
                                      binaryMessenger:[registrar messenger]];
    FileImagePickerPlugin *imageInstance = FileImagePickerPlugin.new;

    [registrar addMethodCallDelegate:imageInstance channel:imageChannel];
}

///file_piker 8.0.6  - (UIViewController *)viewControllerWithWindow:(UIWindow *)window 对应文件方法的 currentViewController

- (FlutterError * _Nullable)onCancelWithArguments:(id _Nullable)arguments {
    self.eventSink = nil;
    return nil;
}

- (FlutterError * _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(nonnull FlutterEventSink)events {
    self.eventSink = events;
    return nil;
}

- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result{
    if (self.result) {
        result([FlutterError errorWithCode:@"multiple_request"
                                   message:@"Cancelled by a second request"
                                   details:nil]);
        self.result = nil;
        return;
    }

    self.result = result;

    self.arguments = call.arguments;

    /// 参数解析

    if ([self.arguments.allKeys containsObject:@"source"]) {
        int imageSource = [[self.arguments objectForKey:@"source"] intValue];
        self.pickType = imageSource==1 ? FileImagePickTypePhotoLibrary:FileImagePickTypeCamera;
    }

    if ([self.arguments.allKeys containsObject:@"imageAllowsVideo"]) {
        BOOL imageAllowsVideo = [[self.arguments objectForKey:@"imageAllowsVideo"] boolValue];
        self.sourceType = imageAllowsVideo?FileImagePickSourceAll:FileImagePickSourceImage;
    }

    if ([self.arguments.allKeys containsObject:@"imageAllowsEditing"]) {
        self.imageAllowsEditing = [[self.arguments objectForKey:@"imageAllowsEditing"] boolValue];

        if (self.imageAllowsEditing) {
            self.sourceType = FileImagePickSourceImage;
        }
    }
    BOOL isMultiplePick = NO;
    if ([self.arguments.allKeys containsObject:@"allowMultipleSelection"]) {
        isMultiplePick = [[self.arguments objectForKey:@"allowMultipleSelection"] boolValue];
        self.selectionLimit = isMultiplePick?0:1;
    }

    if ([self.arguments.allKeys containsObject:@"allowCompression"]) {
        self.imageAllowsCompression = [[self.arguments objectForKey:@"allowCompression"] boolValue];
		self.fileAllowCompression = [[self.arguments objectForKey:@"allowCompression"] boolValue];

    }

    if ([self.arguments.allKeys containsObject:@"withData"]) {
        self.fileWithData = [[self.arguments objectForKey:@"withData"] boolValue];

    }

    if ([self.arguments.allKeys containsObject:@"allowedExtensions"]) {
        self.fileAllowedExtensions = [FileUtils resolveType:call.method withAllowedExtensions: [self.arguments valueForKey:@"allowedExtensions"]];
    }

    if ([self.arguments.allKeys containsObject:@"maxDuration"]) {
        self.videoMaximumDuration = [[self.arguments objectForKey:@"maxDuration"] doubleValue];
    }

    if ([self.arguments.allKeys containsObject:@"maxWidth"]&&[self.arguments.allKeys containsObject:@"maxHeight"]) {
        self.imageMaxWidth = [self.arguments objectForKey:@"maxWidth"];
    }

    if ([self.arguments.allKeys containsObject:@"maxHeight"]) {
        self.imageMaxHeight = [self.arguments objectForKey:@"maxHeight"];
    }

    if ([self.arguments.allKeys containsObject:@"imageQuality"]) {
        self.imageQuality = [self.arguments objectForKey:@"imageQuality"];
    }

    if ([self.arguments.allKeys containsObject:@"customSavePath"]) {
        self.customSavePath = [self.arguments objectForKey:@"customSavePath"];

        if(![self fi_isBlankString:self.customSavePath]) {

            [[NSUserDefaults standardUserDefaults] setValue: self.customSavePath  forKey:@"customSavePath"];
        }
    }

    if ([self.arguments.allKeys containsObject:@"imageHEICtoJPG"]) {
        self.imageHEICtoJPG = [[self.arguments objectForKey:@"imageHEICtoJPG"] boolValue];
    }

    if ([self.arguments.allKeys containsObject:@"isRotation"]) {
        self.isRotation = [[self.arguments objectForKey:@"isRotation"] boolValue];
    }
    // 方法解析

    /// 不支持 HEIC格式预览，强制转化
    self.imageHEICtoJPG = YES;


    if ([@"pickImage" isEqualToString:call.method]) {

        [self pickImage];
        return;
    }

    if ([@"pickMultiImage" isEqualToString:call.method]) {
        self.pickType = FileImagePickTypePhotoLibrary;

        [self pickMultiImage];
        return;
    }

    if ([@"pickVideo" isEqualToString:call.method]) {
        self.sourceType = FileImagePickSourceVideo;
        [self pickImage];
        return;
    }

    if([@"clear" isEqualToString:call.method]) {
        self.result([NSNumber numberWithBool: [FileUtils clearTemporaryFiles]]);
        self.result = nil;
        return;
    }

    if([@"dir" isEqualToString:call.method]) {
        if (@available(iOS 13, *)) {
            self.fileIsDirectory = YES;
            //[self pickFile];
			[self resolvePickDocumentWithMultiPick:NO pickDirectory:YES];
        } else {
            self.result([self getDocumentDirectory]);
            self.result = nil;
        }
        return;
    }

    if ([@"customPickImage" isEqualToString:call.method]) {

        [self pickImage];

        return;
    }

    if ([@"customPickMultiImage" isEqualToString:call.method]) {
        self.pickType = FileImagePickTypePhotoLibrary;

        [self pickMultiImage];

        return;
    }


    if([@"any" isEqualToString:call.method] || [@"custom" containsString:call.method]) {
        self.fromFile = YES;

        if(self.fileAllowedExtensions == nil) {
            self.result([FlutterError errorWithCode:@"Unsupported file extension"
                                        message:@"If you are providing extension filters make sure that you are only using FileType.custom and the extension are provided without the dot, (ie., jpg instead of .jpg). This could also have happened because you are using an unsupported file extension. If the problem persists, you may want to consider using FileType.all instead."
                                        details:nil]);
            self.result = nil;
        } else if(self.fileAllowedExtensions != nil) {
            self.fileIsDirectory = NO;
            [self resolvePickDocumentWithMultiPick:isMultiplePick pickDirectory:NO];
            //[self pickFile];
        }

        return;
    }

    if([@"video" isEqualToString:call.method] || [@"image" isEqualToString:call.method] || [@"media" isEqualToString:call.method]) {
        self.fromFile = YES;

        if ([@"video" isEqualToString:call.method]) {
            self.sourceType = FileImagePickSourceVideo;
        } else if ([@"image" isEqualToString:call.method]) {
            self.sourceType = FileImagePickSourceImage;
        } else {
            self.sourceType = FileImagePickSourceAll;
        }

        //[self pickMultiImage];
		[self resolvePickMedia:[FileUtils resolveMediaType:call.method] withMultiPick:isMultiplePick withCompressionAllowed:self.fileAllowCompression];
        return;
    }

    if([@"audio" isEqualToString:call.method]) {
        self.fromFile = YES;

        //[self pickAudio];
		[self resolvePickAudioWithMultiPick: isMultiplePick];
        return;
    }

	if([@"save" isEqualToString:call.method]){
	    NSString *fileName = [self.arguments valueForKey:@"fileName"];
        NSString *fileType = [self.arguments valueForKey:@"fileType"];
        NSString *initialDirectory = [self.arguments valueForKey:@"initialDirectory"];
        FlutterStandardTypedData *bytes = [self.arguments valueForKey:@"bytes"];
        [self saveFileWithName:fileName fileType:fileType initialDirectory:initialDirectory bytes: bytes];
		return;
	}

    result(FlutterMethodNotImplemented);
    self.result = nil;
}

- (NSString*)getDocumentDirectory {
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return paths.firstObject;
}


- (NSNumber *)getDesiredImageQuality:(NSNumber *)imageQuality {
  if (![imageQuality isKindOfClass:[NSNumber class]]) {
    imageQuality = @1;
  } else if (imageQuality.intValue < 0 || imageQuality.intValue > 100) {
    imageQuality = @1;
  } else {
    imageQuality = @([imageQuality floatValue] / 100);
  }
  return imageQuality;
}

- (void)handleResult:(id)files {
    self.result([FileUtils resolveFileInfo: [files isKindOfClass: [NSArray class]] ? files : @[files] withData:self.fileWithData]);
    self.result = nil;
}

- (void)handleSavedPathList:(NSArray *)pathList {
  if (!self.result) {
    return;
  }

  if (pathList) {
      NSMutableArray *pathArr = NSMutableArray.array;
      for (id path in pathList) {
          if ([path isKindOfClass:NSString.class]) {
              [pathArr addObject:path];
          }
          if([path isKindOfClass:NSMutableDictionary.class]) {
              [pathArr addObject:path];
          }
      }
      self.result(pathArr);
  } else {
    // This should never happen.
    self.result([FlutterError errorWithCode:@"create_error"
                                    message:@"pathList should not be nil"
                                    details:nil]);
  }
  self.result = nil;
  _arguments = nil;
}

- (NSMutableArray *)createNSMutableArrayWithSize:(NSUInteger)size {
  NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:size];
  for (int i = 0; i < size; [mutableArray addObject:[NSNull null]], i++)
    ;
  return mutableArray;
}



#pragma mark - 获取当前控制器
/// 获取当前控制器
- (UIViewController *)currentViewController{
    UIWindow *windowToUse = nil;
    for (UIWindow *window in [UIApplication sharedApplication].windows) {
        if (window.isKeyWindow) {
            windowToUse = window;
            break;
        }
    }

    UIViewController *topController = windowToUse.rootViewController;
    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }
    return topController;
}

///file_picker 8.0.6 保存文件
- (void)saveFileWithName:(NSString*)fileName fileType:(NSString *)fileType initialDirectory:(NSString*)initialDirectory bytes:(FlutterStandardTypedData*)bytes{
    self.isSaveFile = YES;
    NSFileManager* fm = [NSFileManager defaultManager];
    NSURL* documentsDirectory = [fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0];
    NSURL* destinationPath = [documentsDirectory URLByAppendingPathComponent:fileName];
    NSError* error;
    if ([fm fileExistsAtPath:destinationPath.path]) {
        [fm removeItemAtURL:destinationPath error:&error];
        if (error != nil) {
            _result([FlutterError errorWithCode:@"Failed to remove file" message:[error debugDescription] details:nil]);
            error = nil;
        }
    }
    if(bytes != nil){
        [bytes.data writeToURL:destinationPath options:NSDataWritingAtomic error:&error];
        if (error != nil) {
            _result([FlutterError errorWithCode:@"Failed to write file" message:[error debugDescription] details:nil]);
            error = nil;
        }
    }
    self.documentPickerController = [[UIDocumentPickerViewController alloc] initWithURL:destinationPath inMode:UIDocumentPickerModeExportToService];
    self.documentPickerController.delegate = self;
    self.documentPickerController.presentationController.delegate = self;
    if(@available(iOS 13, *)){
       if(![[NSNull null] isEqual:initialDirectory] && ![@"" isEqualToString:initialDirectory]){
            self.documentPickerController.directoryURL = [NSURL URLWithString:initialDirectory];
        }
    }
    [[self currentViewController] presentViewController:self.documentPickerController animated:YES completion:nil];
}

///file_picker 8.0.6 PICKER_DOCUMENT
- (void)resolvePickDocumentWithMultiPick:(BOOL)allowsMultipleSelection pickDirectory:(BOOL)isDirectory {
    self.isSaveFile = NO;
    @try{
        self.documentPickerController = [[UIDocumentPickerViewController alloc]
                                         initWithDocumentTypes: isDirectory ? @[@"public.folder"] : self.fileAllowedExtensions
                                         inMode: isDirectory ? UIDocumentPickerModeOpen : UIDocumentPickerModeImport];
    } @catch (NSException * e) {
        Log(@"Couldn't launch documents file picker. Probably due to iOS version being below 11.0 and not having the iCloud entitlement. If so, just make sure to enable it for your app in Xcode. Exception was: %@", e);
        _result = nil;
        return;
    }
    self.documentPickerController.modalPresentationStyle = UIModalPresentationFullScreen;//自定义增加，参考已有方法pickFile
    self.documentPickerController.allowsMultipleSelection = allowsMultipleSelection;
    self.documentPickerController.delegate = self;
    self.documentPickerController.presentationController.delegate = self;

    [[self currentViewController] presentViewController:self.documentPickerController animated:YES completion:nil];
}

///file_picker 8.0.6 image\video\media
- (void) resolvePickMedia:(MediaType)type withMultiPick:(BOOL)multiPick withCompressionAllowed:(BOOL)allowCompression  {

#ifdef PHPicker
    if (@available(iOS 14, *)) {
        PHPickerConfiguration *config = [[PHPickerConfiguration alloc] init];
        config.filter = type == IMAGE ? [PHPickerFilter imagesFilter] : type == VIDEO ? [PHPickerFilter videosFilter] : [PHPickerFilter anyFilterMatchingSubfilters:@[[PHPickerFilter videosFilter], [PHPickerFilter imagesFilter]]];
        config.preferredAssetRepresentationMode = self.fileAllowCompression ? PHPickerConfigurationAssetRepresentationModeCompatible : PHPickerConfigurationAssetRepresentationModeCurrent;

        if(multiPick) {
            config.selectionLimit = 0;
        }

        PHPickerViewController *pickerViewController = [[PHPickerViewController alloc] initWithConfiguration:config];
        pickerViewController.delegate = self;
        pickerViewController.presentationController.delegate = self;
        [[self currentViewController] presentViewController:pickerViewController animated:YES completion:nil];
        return;
    }
#endif

    if(multiPick) {
        [self resolveMultiPickFromGallery:type withCompressionAllowed:allowCompression];
        return;
    }

    NSArray<NSString*> * videoTypes = @[(NSString*)kUTTypeMovie, (NSString*)kUTTypeAVIMovie, (NSString*)kUTTypeVideo, (NSString*)kUTTypeMPEG4];
    NSArray<NSString*> * imageTypes = @[(NSString *)kUTTypeImage];

    self.galleryPickerController = [[UIImagePickerController alloc] init];
    self.galleryPickerController.delegate = self;
    self.galleryPickerController.presentationController.delegate = self;
    self.galleryPickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;

    switch (type) {
        case IMAGE:
            self.galleryPickerController.mediaTypes = imageTypes;
            self.galleryPickerController.imageExportPreset = allowCompression ? UIImagePickerControllerImageURLExportPresetCompatible : UIImagePickerControllerImageURLExportPresetCurrent;
            break;

        case VIDEO:
            self.galleryPickerController.mediaTypes = videoTypes;
            self.galleryPickerController.videoExportPreset = allowCompression ? AVAssetExportPresetHighestQuality : AVAssetExportPresetPassthrough;
            break;

        default:
            self.galleryPickerController.mediaTypes = [videoTypes arrayByAddingObjectsFromArray:imageTypes];
            break;
    }

    [[self currentViewController] presentViewController:self.galleryPickerController animated:YES completion:nil];


}

- (void) resolveMultiPickFromGallery:(MediaType)type withCompressionAllowed:(BOOL)allowCompression {
    DKImagePickerController * dkImagePickerController = [[DKImagePickerController alloc] init];

    UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"" message:@"" preferredStyle:UIAlertControllerStyleAlert];
    UIActivityIndicatorView* indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];

    UIViewController *currentViewController = [self currentViewController];
    if(_eventSink == nil) {
        // Create alert dialog for asset caching
        [alert.view setCenter: currentViewController.view.center];
        [alert.view addConstraint: [NSLayoutConstraint constraintWithItem:alert.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:100]];

        // Create a default loader if user don't provide a status handler
        indicator.hidesWhenStopped = YES;
        [indicator setCenter: alert.view.center];
        indicator.autoresizingMask = (UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin);
        [alert.view addSubview: indicator];
    }

    DKImageAssetExporterConfiguration * exportConfiguration = [[DKImageAssetExporterConfiguration alloc] init];
    exportConfiguration.imageExportPreset = allowCompression ? DKImageExportPresentCompatible : DKImageExportPresentCurrent;
    exportConfiguration.videoExportPreset = allowCompression ? AVAssetExportPresetHighestQuality : AVAssetExportPresetPassthrough;
    dkImagePickerController.exporter = [dkImagePickerController.exporter initWithConfiguration:exportConfiguration];

    dkImagePickerController.exportsWhenCompleted = YES;
    dkImagePickerController.showsCancelButton = YES;
    dkImagePickerController.sourceType = DKImagePickerControllerSourceTypePhoto;
    dkImagePickerController.assetType = type == VIDEO ? DKImagePickerControllerAssetTypeAllVideos : type == IMAGE ? DKImagePickerControllerAssetTypeAllPhotos : DKImagePickerControllerAssetTypeAllAssets;

    // Export status changed
    [dkImagePickerController setExportStatusChanged:^(enum DKImagePickerControllerExportStatus status) {

        if(status == DKImagePickerControllerExportStatusExporting && dkImagePickerController.selectedAssets.count > 0){
            Log("Exporting assets, this operation may take a while if remote (iCloud) assets are being cached.");

            if(self.eventSink != nil){//->_ 改为.
                self.eventSink([NSNumber numberWithBool:YES]);
            } else {
                [indicator startAnimating];
                [currentViewController showViewController:alert sender:nil];
            }

        } else {
            if(self.eventSink != nil) {//->_ 改为.
                self.eventSink([NSNumber numberWithBool:NO]);
            } else {
                [indicator stopAnimating];
                [alert dismissViewControllerAnimated:YES completion:nil];
            }

        }
    }];

    // Did cancel
    [dkImagePickerController setDidCancel:^(){
        self.result(nil);//->_ 改为.
        self.result = nil;
    }];

    // Did select
    [dkImagePickerController setDidSelectAssets:^(NSArray<DKAsset*> * __nonnull DKAssets) {
        NSMutableArray<NSURL*>* paths = [[NSMutableArray<NSURL*> alloc] init];

        for(DKAsset * asset in DKAssets) {
            if(asset.localTemporaryPath.absoluteURL != nil) {
                [paths addObject:asset.localTemporaryPath.absoluteURL];
            }
        }

        [self handleResult: paths];
    }];

    [[self currentViewController] presentViewController:dkImagePickerController animated:YES completion:nil];
}

///PICKER_AUDIO
- (void) resolvePickAudioWithMultiPick:(BOOL)isMultiPick {
    self.audioPickerController = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio];
    self.audioPickerController.delegate = self;
    self.audioPickerController.presentationController.delegate = self;
    self.audioPickerController.showsCloudItems = YES;
    self.audioPickerController.allowsPickingMultipleItems = isMultiPick;

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        if([self currentViewController].presentedViewController == nil){
            Log("Exporting assets, this operation may take a while if remote (iCloud) assets are being cached.");
        }
    });


    [[self currentViewController] presentViewController:self.audioPickerController animated:YES completion:nil];
}

#pragma mark - 单选图片
/// 单选图片
- (void)pickImage{
    UIImagePickerController *imagePickerController = UIImagePickerController.new;
    imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
    imagePickerController.delegate = self;
    if (self.pickType==FileImagePickTypeCamera) {
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
        }
    } else {
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
            imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

            /// 文件类型过滤
            if (self.sourceType==FileImagePickSourceImage) {
                imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
            } else if (self.sourceType==FileImagePickSourceVideo) {
                imagePickerController.mediaTypes = @[(NSString *)kUTTypeMovie];

                imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;

                if (self.videoMaximumDuration>0) {
                    imagePickerController.videoMaximumDuration = self.videoMaximumDuration;
                }
            } else {
                imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage,(NSString *)kUTTypeMovie];

                imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
                if (self.videoMaximumDuration>0) {
                    imagePickerController.videoMaximumDuration = self.videoMaximumDuration;
                }
            }

        }
    }

    /// 单选图片是否可裁剪
    if (self.sourceType==FileImagePickSourceImage) {
        imagePickerController.allowsEditing = self.imageAllowsEditing;
    }

    [[self currentViewController] presentViewController:imagePickerController animated:YES completion:nil];

}

#pragma mark UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [picker dismissViewControllerAnimated:YES completion:nil];

    if (self.result==nil) {
        return;
    }

    NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];

    if (videoURL != nil) {
      // 同一文件没办法去重

//        if (@available(iOS 13.0, *)) {
//          NSString *fileName = [videoURL lastPathComponent];
//          NSURL *destination =
//              [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]];
//
//          if ([[NSFileManager defaultManager] isReadableFileAtPath:[videoURL path]]) {
//            NSError *error;
//            if (![[videoURL path] isEqualToString:[destination path]]) {
//              [[NSFileManager defaultManager] copyItemAtURL:videoURL toURL:destination error:&error];
//
//              if (error) {
//                self.result([FlutterError errorWithCode:@"flutter_image_picker_copy_video_error"
//                                                message:@"Could not cache the video file."
//                                                details:nil]);
//                self.result = nil;
//                return;
//              }
//            }
//            videoURL = destination;
//          }
//        }

        self.result(videoURL.path);
        self.result = nil;
        self.arguments = nil;

        return;
    }

    if (self.pickType==FileImagePickTypePhotoLibrary&&self.imageAllowsEditing==NO) {
        if (@available(iOS 11.0, *)) {
            NSURL *imageURL = [info objectForKey:UIImagePickerControllerImageURL];
            if (imageURL!=nil) {
                self.result(imageURL.path);
                self.result = nil;
                self.arguments = nil;
                return;
            }

        }
    }

    UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];

    if (image!=nil) {
        NSString *savedPath = [FLTImagePickerPhotoAssetUtil saveEditedImage:image];
        self.result(savedPath);
        self.result = nil;
        self.arguments = nil;
        return;
    }

    image = [info objectForKey:UIImagePickerControllerOriginalImage];

    if ((self.imageMaxWidth!=nil&&self.imageMaxHeight!=nil)&&([self.imageMaxWidth isKindOfClass:NSNumber.class]&&[self.imageMaxHeight isKindOfClass:NSNumber.class])) {
      image = [FLTImagePickerImageUtil scaledImage:image maxWidth:self.imageMaxWidth maxHeight:self.imageMaxHeight isMetadataAvailable:YES];
    }

    NSNumber *desiredImageQuality;
    if (self.imageQuality!=nil&&[self.imageQuality isKindOfClass:NSNumber.class]) {
        desiredImageQuality = [self getDesiredImageQuality:self.imageQuality];
    }

    PHAsset *originalAsset = [FLTImagePickerPhotoAssetUtil getAssetFromImagePickerInfo:info];
    if (originalAsset!=nil) {
        [[PHImageManager defaultManager] requestImageDataForAsset:originalAsset options:nil resultHandler:^(NSData *_Nullable imageData, NSString *_Nullable dataUTI, UIImageOrientation orientation, NSDictionary *_Nullable info) {

            if (self.imageHEICtoJPG) {
                //增加 判断如果heic图片 转换一次
                __block BOOL isHEIF = NO;
                if (@available(iOS 9.0, *)) {
                    NSArray *resourceList = [PHAssetResource assetResourcesForAsset:originalAsset];
                    [resourceList enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                        PHAssetResource *resource = obj;
                        NSString *UTI = resource.uniformTypeIdentifier;
                        if ([UTI isEqualToString:@"public.heif"] || [UTI isEqualToString:@"public.heic"]) {
                            isHEIF = YES;
                            *stop = YES;
                        }
                    }];
                } else {
                    NSString *UTI = [originalAsset valueForKey:@"uniformTypeIdentifier"];
                    isHEIF = [UTI isEqualToString:@"public.heif"] || [UTI isEqualToString:@"public.heic"];
                }

                if (isHEIF) {
                    CIImage *ciImage = [CIImage imageWithData:imageData];
                    CIContext *context = [CIContext context];

                    if (@available(iOS 10.0, *)) {
                        imageData = [context JPEGRepresentationOfImage:ciImage colorSpace:ciImage.colorSpace options:@{}];
                    } else {
                        // Fallback on earlier versions
                    }

                }
            }

            NSString *savedPath = [FLTImagePickerPhotoAssetUtil saveImageWithOriginalImageData:imageData image:image maxWidth:self.imageMaxWidth maxHeight:self.imageMaxHeight imageQuality:self.imageQuality];
            self.result(savedPath);
            self.result = nil;
            self.arguments = nil;

        }];

    } else {

        if(self.isRotation) {
            [self fixOrientation:image result:^(UIImage *newImage, BOOL isRotation) {
                NSString *savedPath = [FLTImagePickerPhotoAssetUtil saveImageWithPickerInfo:info image:newImage imageQuality:desiredImageQuality isRotation:isRotation];
                self.result(savedPath);
                self.result = nil;
                self.arguments = nil;
            }];
        } else {
            NSString *savedPath = [FLTImagePickerPhotoAssetUtil saveImageWithPickerInfo:info image:image imageQuality:desiredImageQuality];
            self.result(savedPath);
            self.result = nil;
            self.arguments = nil;
        }
    }
}

/// 重绘图片，解决 中台接收到的图片，绘制表格时图片倒了问题
- (void)fixOrientation:(UIImage *)aImage result:(void(^)(UIImage *newImage, BOOL isRotation))result{

    // No-op if the orientation is already correct
    if (aImage.imageOrientation == UIImageOrientationUp) {
        result(aImage, NO);
        return;
    }
    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;

    switch (aImage.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;

        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }

    switch (aImage.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;

        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }

    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
                                             CGImageGetBitsPerComponent(aImage.CGImage), 0,
                                             CGImageGetColorSpace(aImage.CGImage),
                                             CGImageGetBitmapInfo(aImage.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (aImage.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
            break;

        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
            break;
    }

    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    result(img, YES);
    return;
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [picker dismissViewControllerAnimated:YES completion: nil];

    self.result(nil);
    self.result = nil;
}

#pragma mark - 多选图片
/// 多选图片
- (void)pickMultiImage{
//    if (@available(iOS 14, *)) {
//        [self pickImageWithPHPicker];
//    } else {
        [self pickImageWithCustom];
//    }
}

/// iOS14相册多选方式
- (void)pickImageWithPHPicker API_AVAILABLE(ios(14)){

    PHPickerConfiguration *config = [[PHPickerConfiguration alloc] initWithPhotoLibrary:PHPhotoLibrary.sharedPhotoLibrary];
    config.preferredAssetRepresentationMode = self.imageAllowsCompression ? PHPickerConfigurationAssetRepresentationModeCompatible : PHPickerConfigurationAssetRepresentationModeCurrent;
    // 0 多选无上限
    config.selectionLimit = self.selectionLimit;

    if (self.sourceType==FileImagePickSourceImage) {
        config.filter = [PHPickerFilter imagesFilter];
    } else if (self.sourceType==FileImagePickSourceVideo) {
        config.filter = [PHPickerFilter videosFilter];
    }

    PHPickerViewController *pickerViewController = [[PHPickerViewController alloc] initWithConfiguration:config];
    pickerViewController.delegate = self;
    pickerViewController.modalPresentationStyle = UIModalPresentationFullScreen;

    [[self currentViewController] presentViewController:pickerViewController animated:YES completion:nil];
}

#pragma mark PHPickerViewControllerDelegate
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14)){
    [picker dismissViewControllerAnimated:YES completion:nil];

    if (self.result==nil) {
        return;
    }
	if(self.group != nil) {
        return;
    }

    if (results==nil||results.count==0) {
        self.result(nil);
        self.result = nil;
        return;
    }

    if(self.eventSink != nil) {
        self.eventSink([NSNumber numberWithBool:YES]);
    }

    NSMutableArray<NSURL *> * urls = [[NSMutableArray alloc] initWithCapacity:results.count];

    if (self.fromFile==false) {
        dispatch_queue_t backgroundQueue =
            dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
        dispatch_async(backgroundQueue, ^{
          NSOperationQueue *operationQueue = [NSOperationQueue new];
            NSMutableArray *pathList = [self createNSMutableArrayWithSize:results.count];

          for (int i = 0; i < results.count; i++) {
            PHPickerResult *result = results[i];

            FLTPHPickerSaveImageToPathOperation *operation =
                [[FLTPHPickerSaveImageToPathOperation alloc] initWithResult:result
                                                                  maxHeight:self.imageMaxHeight
                                                                   maxWidth:self.imageMaxWidth
                                                        desiredImageQuality:[self getDesiredImageQuality:self.imageQuality]
                                                             savedPathBlock:^(NSString *savedPath) {
                                                               pathList[i] = savedPath;
                                                             }];
            [operationQueue addOperation:operation];
          }
          [operationQueue waitUntilAllOperationsAreFinished];
          dispatch_async(dispatch_get_main_queue(), ^{
            [self handleSavedPathList:pathList];
          });
        });

        return;
    }


    __block dispatch_group_t group = dispatch_group_create();
	self.group = group;

    __block NSError * blockError;
    
    for (NSInteger index = 0; index < results.count; ++index) {
        [urls addObject:[NSURL URLWithString:@""]];
        dispatch_group_enter(self.group);
		PHPickerResult * result = [results objectAtIndex: index];
        [result.itemProvider loadFileRepresentationForTypeIdentifier:@"public.item" completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
            
            if(url == nil) {
                blockError = error;
                NSLog(@"Could not load the picked given file: %@", blockError);
                dispatch_group_leave(self.group);
                return;
            }
			long timestamp = (long)([[NSDate date] timeIntervalSince1970] * 1000);
            NSString * filenameWithoutExtension = [url.lastPathComponent stringByDeletingPathExtension];
            NSString * fileExtension = url.pathExtension;
            NSString * filename = [NSString stringWithFormat:@"%@-%ld.%@", filenameWithoutExtension, timestamp, fileExtension];
            //NSString * filename = url.lastPathComponent;
            NSString * extension = [filename pathExtension];
            NSFileManager * fileManager = [[NSFileManager alloc] init];
            NSURL * cachedUrl;

            // Check for live photos
            if(self.fileAllowCompression && [extension isEqualToString:@"pvt"]) {
                NSArray * files = [fileManager contentsOfDirectoryAtURL:url includingPropertiesForKeys:@[] options:NSDirectoryEnumerationSkipsHiddenFiles error:nil];
                
                for (NSURL * item in files) {
                    if (UTTypeConformsTo(UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, CFBridgingRetain([item pathExtension]), NULL), kUTTypeImage)) {
                        NSData *assetData = [NSData dataWithContentsOfURL:item];
                        //Convert any type of image to jpeg
                        NSData *convertedImageData = UIImageJPEGRepresentation([UIImage imageWithData:assetData], 1.0);
                        //Get meta data from asset
                        NSDictionary *metaData = [ImageUtils getMetaDataFromImageData:assetData];
                        //Append meta data into jpeg of live photo
                        NSData *data = [ImageUtils imageFromImage:convertedImageData withMetaData:metaData];
                        //Save jpeg
                        NSString * filenameWithoutExtension = [filename stringByDeletingPathExtension];
                        NSString * tmpFile = [NSTemporaryDirectory() stringByAppendingPathComponent:[filenameWithoutExtension stringByAppendingString:@".jpeg"]];
						//UIImage * img = [UIImage imageWithContentsOfFile:item.path];
                        //NSString * fileName = [[item.path lastPathComponent] stringByDeletingPathExtension];
                        //NSData * data = UIImageJPEGRepresentation(img, 1);
                        //NSString * tmpFile = [NSTemporaryDirectory() stringByAppendingPathComponent:[fileName stringByAppendingString:@".jpeg"]];
                        cachedUrl = [NSURL fileURLWithPath: tmpFile];

                        if([fileManager fileExistsAtPath:tmpFile]) {
                            [fileManager removeItemAtPath:tmpFile error:nil];
                        }

                        if([fileManager createFileAtPath:tmpFile contents:data attributes:nil]) {
                            filename = tmpFile;
                        } else {
                            NSLog(@"%@ Error while caching picked Live photo", self);
                        }
                        break;
                    }
                }
            } else {
                NSString * cachedFile = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];

                if([fileManager fileExistsAtPath:cachedFile]) {
                    [fileManager removeItemAtPath:cachedFile error:NULL];
                }

                cachedUrl = [NSURL fileURLWithPath: cachedFile];

                NSError *copyError;
                [fileManager copyItemAtURL: url toURL: cachedUrl error: &copyError];

                if (copyError) {
                    NSLog(@"%@ Error while caching picked file: %@", self, copyError);
                    return;
                }
            }
            
            
            //[urls addObject:cachedUrl];
			[urls replaceObjectAtIndex:index withObject:cachedUrl];
            dispatch_group_leave(self.group);
        }];
    }

    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
        group = nil;
        if(self.eventSink != nil) {
            self.eventSink([NSNumber numberWithBool:NO]);
        }

        if(blockError) {
            self.result([FlutterError errorWithCode:@"file_picker_error" message:@"Temporary file could not be created" details:blockError.description]);
            self.result = nil;
            return;
        }
        [self handleResult:urls];
    });

}

/// 自定义相册多选
- (void)pickImageWithCustom{
    DKImagePickerController * customImagePickerController = [[DKImagePickerController alloc] init];
    customImagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;


    DKImageAssetExporterConfiguration * exportConfiguration = [[DKImageAssetExporterConfiguration alloc] init];
    if (self.imageHEICtoJPG) {
        exportConfiguration.imageExportPreset = DKImageExportPresentCompatible;
    } else {
        exportConfiguration.imageExportPreset = self.imageAllowsCompression ? DKImageExportPresentCompatible : DKImageExportPresentCurrent;
    }

    exportConfiguration.videoExportPreset = self.imageAllowsCompression ? AVAssetExportPresetHighestQuality : AVAssetExportPresetPassthrough;
    if (![self fi_isBlankString:self.customSavePath]) {
        [exportConfiguration setExportDirectory:[NSURL fileURLWithPath:self.customSavePath]];
    }
    DKImageAssetExporter *exporter = [[DKImageAssetExporter alloc] initWithConfiguration:exportConfiguration];
    customImagePickerController.exporter = exporter ;

    customImagePickerController.exportsWhenCompleted = YES;
    customImagePickerController.showsCancelButton = YES;

    customImagePickerController.sourceType = DKImagePickerControllerSourceTypePhoto;

    if (self.sourceType==FileImagePickSourceImage) {
        customImagePickerController.assetType = DKImagePickerControllerAssetTypeAllPhotos;
    } else if (self.sourceType==FileImagePickSourceVideo) {
        customImagePickerController.assetType = DKImagePickerControllerAssetTypeAllVideos;
    } else {
        customImagePickerController.assetType = DKImagePickerControllerAssetTypeAllAssets;
    }


    [customImagePickerController setExportStatusChanged:^(enum DKImagePickerControllerExportStatus status) {
        if(status == DKImagePickerControllerExportStatusExporting && customImagePickerController.selectedAssets.count > 0){
            NSLog(@"Exporting assets, this operation may take a while if remote (iCloud) assets are being cached.");

            if(self.eventSink != nil){
                self.eventSink([NSNumber numberWithBool:YES]);
            }
        } else {
            if(self.eventSink != nil) {
                self.eventSink([NSNumber numberWithBool:NO]);
            }
        }

    }];


    [customImagePickerController setDidCancel:^(){
        self.result(nil);
        self.result = nil;
    }];


    [customImagePickerController setDidSelectAssets:^(NSArray<DKAsset*> * __nonnull DKAssets) {
        NSMutableArray *urlPaths = [NSMutableArray array];
        for(DKAsset * asset in DKAssets) {
            NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
            if(asset.localTemporaryPath.absoluteURL != nil) {
                [dic setValue:asset.localTemporaryPath.path forKey:@"path"];

            }
            [dic setValue:asset.fileName forKey:@"name"];
            [dic setValue:@(asset.fileSize) forKey:@"size"];
            // 创建一个日期格式器
//            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

            // 设置日期格式（YYYY-MM-DD HH:mm:ss）
//            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

            // 将NSDate对象转换为NSString
//            NSString *dateString = [dateFormatter stringFromDate:asset.originalAsset.creationDate];
            [dic setValue:@([asset.originalAsset.creationDate timeIntervalSince1970] * 1000) forKey:@"createTime"];

            CGFloat latitude = asset.location.coordinate.latitude;
            CGFloat longitude = asset.location.coordinate.longitude;
            [dic setValue:@(latitude) forKey:@"latitude"];
            [dic setValue:@(longitude) forKey:@"longitude"];
            [urlPaths addObject:dic];

        }
        if (self.fromFile) {
            [self handleResult:urlPaths];
        } else {
            [self handleSavedPathList:urlPaths];
        }
        
    }];
    
    
    [[self currentViewController] presentViewController:customImagePickerController animated:YES completion:nil];
}

#pragma mark - 选择文件
/// 选择文件
- (void)pickFile{
    // 设置文件类型
    NSArray *documentTypes = self.fileIsDirectory ? @[@"public.folder"] : self.fileAllowedExtensions;
    
    UIDocumentPickerViewController *documentPickerViewController = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:documentTypes inMode:self.fileIsDirectory ? UIDocumentPickerModeOpen : UIDocumentPickerModeImport];
    documentPickerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
    documentPickerViewController.delegate = self;
    
    documentPickerViewController.navigationController.navigationBar.translucent = NO;
    
    [[self currentViewController] presentViewController:documentPickerViewController animated:YES completion:nil];
}

#pragma mark UIDocumentPickerDelegate
- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller{

    self.result(nil);
    self.result = nil;
    [controller dismissViewControllerAnimated:YES completion:nil];
}

- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
    [controller dismissViewControllerAnimated:YES completion:nil];
	if(self.isSaveFile){
        self.result(url);
        self.result = nil;
        return;
    }
    [self handleResult:url];
}

- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls{
    
    [controller dismissViewControllerAnimated:YES completion:nil];
    
    if(self.result == nil) {
        return;
    }
    if(self.isSaveFile){
        self.result(urls[0].path);
        self.result = nil;
        return;
    }
	NSMutableArray<NSURL *> *newUrls = urls;
	if(controller.documentPickerMode == UIDocumentPickerModeImport) {
        newUrls = [NSMutableArray new];
        for (NSURL *url in urls) {
            // Create file URL to temporary folder
            NSURL *tempURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
            // Append filename (name+extension) to URL
            tempURL = [tempURL URLByAppendingPathComponent:url.lastPathComponent];
            NSError *error;
            // If file with same name exists remove it (replace file with new one)
            if ([[NSFileManager defaultManager] fileExistsAtPath:tempURL.path]) {
                [[NSFileManager defaultManager] removeItemAtPath:tempURL.path error:&error];
                if (error) {
                    NSLog(@"%@", error.localizedDescription);
                }
            }
            // Move file from app_id-Inbox to tmp/filename
            [[NSFileManager defaultManager] moveItemAtPath:url.path toPath:tempURL.path error:&error];
            if (error) {
                NSLog(@"%@", error.localizedDescription);
            } else {
                [newUrls addObject:tempURL];
            }
        }
    }
    if(controller.documentPickerMode == UIDocumentPickerModeOpen) {
        self.result([newUrls objectAtIndex:0].path);
        self.result = nil;
        return;
    }
    
    [self handleResult: newUrls];
}

#pragma mark - 选择媒体
/// 选择媒体
- (void)pickAudio {
    
    MPMediaPickerController *mediaPickerController = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio];
    mediaPickerController.delegate = self;
    mediaPickerController.modalPresentationStyle = UIModalPresentationFullScreen;
    mediaPickerController.showsCloudItems = YES;
    mediaPickerController.allowsPickingMultipleItems = self.selectionLimit==0;

    [[self currentViewController] presentViewController:mediaPickerController animated:YES completion:nil];
}

#pragma mark MPMediaPickerControllerDelegate
- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker{
    self.result(nil);
    self.result = nil;
    [mediaPicker dismissViewControllerAnimated:YES completion:nil];
}


- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection{
    [mediaPicker dismissViewControllerAnimated:YES completion:nil];
    
    int numberOfItems = (int)[mediaItemCollection items].count;
    
    if(numberOfItems == 0) {
        return;
    }
    
    if(self.eventSink != nil) {
        self.eventSink([NSNumber numberWithBool:YES]);
    }
    
    NSMutableArray<NSURL *> * urls = [[NSMutableArray alloc] initWithCapacity:numberOfItems];
    
    for(MPMediaItemCollection * item in [mediaItemCollection items]) {
        NSURL * cachedAsset = [FileUtils exportMusicAsset: [item valueForKey:MPMediaItemPropertyAssetURL] withName: [item valueForKey:MPMediaItemPropertyTitle]];
        [urls addObject: cachedAsset];
    }
    
    if(self.eventSink != nil) {
        self.eventSink([NSNumber numberWithBool:NO]);
    }
    
    if(urls.count == 0) {
        NSLog(@"Couldn't retrieve the audio file path, either is not locally downloaded or the file is DRM protected.");
    }
    
    [self handleResult:urls];
}


//file_picker 8.0.6 PICKER_MEDIA
- (void)presentationControllerDidDismiss:(UIPresentationController *)controller {
    Log(@"FilePicker canceled");
    if (self.result != nil) {
        self.result(nil);
        self.result = nil;
    }
}

//file_picker 8.0.6 PICKER_AUDIO 重复方法
//- (void)mediaPickerDidCancel:(MPMediaPickerController *)controller {
//    Log(@"FilePicker canceled");
//    _result(nil);
//    _result = nil;
//    [controller dismissViewControllerAnimated:YES completion:NULL];
//}

//file_picker 8.0.6 PICKER_DOCUMENT 重复方法
//- (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
//    Log(@"FilePicker canceled");
//    _result(nil);
//    _result = nil;
//    [controller dismissViewControllerAnimated:YES completion:NULL];
//}

//file_picker 8.0.6 PICKER_MEDIA 重复方法
//- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
//    Log(@"FilePicker canceled");
//    _result(nil);
//    _result = nil;
//    [picker dismissViewControllerAnimated:YES completion:NULL];
//}

/// 字符串判空
- (BOOL)fi_isBlankString:(NSString *)string{
    if (string == nil || string == NULL) {
           return YES;
       }
       if ([string isKindOfClass:[NSNull class]]) {
           return YES;
       }
    
       if ([string isKindOfClass:[NSString class]]) {
            if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0) {
                return YES;
            }
       }else{
           
           return NO;
       }
    
    return NO;
}


@end
